#include "TwOgreQuaternionVariable.h"

#include "TwOgreWindow.h"
#include "TwOgreWindowManager.h"
#include "OgreStringConverter.h"

namespace TwOgre{
	QuaternionVariable::QuaternionVariable(Window *parent, const Ogre::String& name, bool readOnly, const Ogre::String& label, 
		const Ogre::Quaternion& quat,	const Ogre::String& groupName, const Ogre::String& help) :
		Variable(parent, name, TW_TYPE_QUAT4F), mQuaternion(quat)
	{
		mTweakQuaternion[0] = mQuaternion.x;
		mTweakQuaternion[1] = mQuaternion.y;
		mTweakQuaternion[2] = mQuaternion.z;
		mTweakQuaternion[3] = mQuaternion.w;

		if(readOnly)
		{
			TwAddVarRO(mParent->getTweakBar(), mName.c_str(), TW_TYPE_QUAT4F, &mTweakQuaternion, "showval=true");
		}
		else
		{
			TwAddVarRW(mParent->getTweakBar(), mName.c_str(), TW_TYPE_QUAT4F, &mTweakQuaternion, "arrow='0 0 -1'");
		}

		if(label.compare("") != 0)
		{
			setLabel(label);
		}
		if(groupName.compare("") != 0)
		{
			setGroup(groupName);
		}
		if(help.compare("") != 0)
		{
			setHelp(help);
		}
	}

	QuaternionVariable::QuaternionVariable(QuaternionParams& params) :
		Variable(params.parent_, params.name_, params.type_), mQuaternion(params.value_)
    {
		mTweakQuaternion[0] = mQuaternion.x;
		mTweakQuaternion[1] = mQuaternion.y;
		mTweakQuaternion[2] = mQuaternion.z;
		mTweakQuaternion[3] = mQuaternion.w;
        
        if((params.getCB_ != NULL) && (params.setCB_ != NULL) && (params.data_ != NULL))
        {
            TwAddVarCB(mParent->getTweakBar(), mName.c_str(), params.type_, params.setCB_, params.getCB_, params.data_, "");
        }
        else
        {
		    if(params.readOnly_)
		    {
                TwAddVarRO(mParent->getTweakBar(), mName.c_str(), params.type_, &mTweakQuaternion, "");
		    }
		    else
		    {
                TwAddVarRW(mParent->getTweakBar(), mName.c_str(), params.type_, &mTweakQuaternion, "");
		    }
        }
		
        if(params.label_.compare("") != 0)
		{
			setLabel(params.label_);
		}
		if(params.group_.compare("") != 0)
		{
			setGroup(params.group_);
		}
		if(params.help_.compare("") != 0)
		{
			setHelp(params.help_);
		}
        if(params.arrow_)
		{
            setArrow(params.arrow_, params.arrowAxes_);
        }
    }
	
    QuaternionVariable::~QuaternionVariable()
	{
		TwRemoveVar(mParent->getTweakBar(), mName.c_str());
	}

	void QuaternionVariable::setArrow(bool show, const Ogre::Vector3& axes)
	{
		Ogre::String defString("");
        Ogre::String strAxes = Ogre::StringConverter::toString(axes);
        if(show)
        {
            defString = " '" + mParent->getName() + "'/'" +  mName + "' arrow='" + strAxes + "' ";
        }
        else
        {
    		defString = " '" + mParent->getName() + "'/'" +  mName + "' arrow='0' ";
        }
		TwDefine(defString.c_str());
	}
	
    const Ogre::Quaternion& QuaternionVariable::getQuaternionValue() const
	{
		// Get the values form the control and store them in Ogre's Quaternion
		mQuaternion = Ogre::Quaternion(mTweakQuaternion[3], mTweakQuaternion[0], mTweakQuaternion[1], mTweakQuaternion[2]);
		return mQuaternion;
	}

	void QuaternionVariable::setQuaternionValue(const Ogre::Quaternion& quat)
	{
		// Convert Ogre's Quaternion into a float[4] {XYZW}
		mQuaternion = quat;
		mTweakQuaternion[0] = mQuaternion.x;
		mTweakQuaternion[1] = mQuaternion.y;
		mTweakQuaternion[2] = mQuaternion.z;
		mTweakQuaternion[3] = mQuaternion.w;
	}
}; // End Namespace
